package com.event.controller;


import com.alibaba.fastjson.JSON;
import com.event.pojo.EventLevel;
import com.event.pojo.User;
import com.event.service.EventLevelService;
import com.event.service.UserService;
import com.event.util.Sha1;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.logging.Level;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author 孤雏
 * @since 2021-08-09
 */
@RestController
@RequestMapping("/user")
@CrossOrigin(origins = "*",maxAge = 3600)
@Api(value = "用户信息接口",tags = "用户信息接口")
public class UserController {

    @Autowired
    UserService userService;
    @Autowired
    EventLevelService levelService;
    @Autowired
    RedisTemplate redisTemplate;

    @GetMapping("/login")
    @ApiOperation(value = "用户登录获取权限",notes = "传值进来")
    public JSON login(User user){
        //先sha1加密，再md5加密
        String sha1 = Sha1.getSha1(user.getEduPassword());
        user.setEduPassword(DigestUtils.md5DigestAsHex(sha1.getBytes()));

        List<User> users = userService.selectUser(user);
        Map<Object, Object> map = new ConcurrentHashMap<>();
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(String.valueOf(user.getEduAccount()),user.getEduPassword());
        try {
            subject.login(usernamePasswordToken);
            map.put("status","200");
            map.put("message","ok");
            map.put("sessionId",subject.getSession().getId());
            map.put("data",users.get(0));
            //登录成功
        } catch (UnknownAccountException e) {
            //e.printStackTrace();
            //登录失败:用户名不存在
            map.put("status","500");
            map.put("message","用户名不存在");
            JSON json = (JSON) JSON.toJSON(map);
            return json;
        } catch (IncorrectCredentialsException e) {
            //e.printStackTrace();
            //登录失败:密码错误
            map.put("status","500");
            map.put("message","密码错误");
            JSON json = (JSON) JSON.toJSON(map);
            return json;
        }
        JSON json = (JSON) JSON.toJSON(map);
           return json;
    }
    @GetMapping("/selectUser")
    @ApiOperation(value = "获取用户信息接口,如果传入为空则为查询全部用户",notes = "传值进来")
    public JSON selectUser(User user){
        Map<Object, Object> map = new ConcurrentHashMap<>();
        String msg;
        List<User> users = userService.selectUser(user);
        if(users.size()>0) msg="200";
        else msg="500";
        map.put("code",0);
        map.put("msg",msg);
        map.put("count",users.size());
        map.put("data",users);
        JSON json = (JSON) JSON.toJSON(map);
       return json;
    }
    @GetMapping("/clearRedisUser")
    @ApiOperation(value = "删除用户缓存",notes = "传值进来")
    @CacheEvict(value = "User", allEntries=true)
    public JSON clearRedisUser(){
        Map<Object, Object> map = new ConcurrentHashMap<>();
        map.put("code",0);
        map.put("msg","200");
        JSON json = (JSON) JSON.toJSON(map);
        return json;
    }
    @PostMapping("/collectionUser")
    @ApiOperation(value = "关注用户接口,只需要2个用户id",notes = "传值进来")
    public JSON collectionUser(Long collectionUserId,Long BeCollectionUserId){
        Map<Object, Object> map = new ConcurrentHashMap<>();
        Set<Long> list = new ConcurrentSkipListSet<>();
        Set<Long> BeList = new ConcurrentSkipListSet<>();
        list.add(BeCollectionUserId);
        BeList.add(collectionUserId);
        map.put("code",0);
        try {
            if (redisTemplate.opsForHash().get("collectionUser", collectionUserId.toString())==null){
                redisTemplate.opsForHash().put("collectionUser",collectionUserId.toString(),list);
            }else {
                Set<Long> collectionPost = (Set<Long>) redisTemplate.opsForHash().get("collectionUser", collectionUserId.toString());
                collectionPost.add(BeCollectionUserId);
                redisTemplate.opsForHash().put("collectionUser",collectionUserId.toString(),collectionPost);
            }
            if (redisTemplate.opsForHash().get("BecollectionUser", BeCollectionUserId.toString())==null){
                redisTemplate.opsForHash().put("BecollectionUser",BeCollectionUserId.toString(),BeList);
            }else {
                Set<Long> BeCollectionPost = (Set<Long>) redisTemplate.opsForHash().get("BecollectionUser", BeCollectionUserId.toString());
                BeCollectionPost.add(collectionUserId);
                redisTemplate.opsForHash().put("BecollectionUser",BeCollectionUserId.toString(),BeCollectionPost);
            }
            map.put("msg","200");
        } catch (Exception e) {
            map.put("msg","500");
            e.printStackTrace();
        }
        JSON json = (JSON) JSON.toJSON(map);
        return json;
    }
    @GetMapping("/selectCollectionUser")
    @ApiOperation(value = "查看用户的关注接口",notes = "传值进来")
    public JSON selectCollectionUser(Long collectionUserId){
        Map<Object, Object> map = new ConcurrentHashMap<>();

        map.put("code",0);
        try {
            Set<Long> BeCollectionUserId = (Set<Long>) redisTemplate.opsForHash().get("collectionUser", collectionUserId.toString());
            map.put("msg","200");
            map.put("count",BeCollectionUserId.size());
            map.put("data",BeCollectionUserId);
        } catch (Exception e) {
            map.put("msg","500");
        }
        JSON json = (JSON) JSON.toJSON(map);
        return json;
    }
    @GetMapping("/beSelectCollectionUser")
    @ApiOperation(value = "查看用户的粉丝接口",notes = "传值进来")
    public JSON beSelectCollectionUser(Long beCollectionUserId){
        Map<Object, Object> map = new ConcurrentHashMap<>();
        map.put("code",0);
        try {
            Set<Long> BeCollectionUserId = (Set<Long>) redisTemplate.opsForHash().get("BecollectionUser", beCollectionUserId.toString());
            map.put("msg","200");
            map.put("count",BeCollectionUserId.size());
            map.put("data",BeCollectionUserId);
        } catch (Exception e) {
            map.put("msg","500");
            map.put("count",0);
            e.printStackTrace();
        }
        JSON json = (JSON) JSON.toJSON(map);
        return json;
    }
    @PostMapping("/removeCollectionUser")
    @ApiOperation(value = "取消好友关注接口collectionUserId关注者BeCollectionUserId被关注者",notes = "传值进来")
    public JSON removeCollectionUser(Long collectionUserId,Long BeCollectionUserId){
        Map<Object, Object> map = new ConcurrentHashMap<>();
        map.put("code",0);
        try {
            Set<Long> collectionPost = (Set<Long>) redisTemplate.opsForHash().get("collectionUser", collectionUserId.toString());
                collectionPost.remove(BeCollectionUserId);
                redisTemplate.opsForHash().put("collectionUser",collectionUserId.toString(),collectionPost);

            Set<Long> BeCollectionPost = (Set<Long>) redisTemplate.opsForHash().get("BecollectionUser", BeCollectionUserId.toString());
                BeCollectionPost.remove(collectionUserId);
                redisTemplate.opsForHash().put("BecollectionUser",BeCollectionUserId.toString(),BeCollectionPost);
            map.put("msg","200");
        } catch (Exception e) {
            map.put("msg","500");
            e.printStackTrace();
        }
        JSON json = (JSON) JSON.toJSON(map);
        return json;
    }
    @PostMapping("/updateUser")
    @ApiOperation(value = "传userid更新头像url和昵称",notes = "传值进来")
    public JSON updateUser(User user){
        Map<Object, Object> map = new ConcurrentHashMap<>();
        String msg;
        int i = userService.updateUser(user);
        if(i>0) msg="200";
        else msg="500";
        map.put("code",0);
        map.put("msg",msg);
        return (JSON) JSON.toJSON(map);
    }
    @PostMapping("/nearPeople")
    @ApiOperation(value = "传经纬度和用户id获取附近的人,进入小程序时务必调用!",notes = "传值进来")
    public JSON nearPeople(Integer userId,double longitude,double latitude){
        Map<Object, Object> map = new ConcurrentHashMap<>();
        map.put("code",0);
        try {
            redisTemplate.opsForGeo().add("nearPeople",new Point(longitude,latitude),userId.toString());
            Distance distance = new Distance(20,Metrics.KILOMETERS);
            RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending();
            GeoResults<RedisGeoCommands.GeoLocation<String>>  results = redisTemplate.opsForGeo().radius("nearPeople",userId.toString(),distance,args);
            List<GeoResult<RedisGeoCommands.GeoLocation<String>>> content = results.getContent();
            content = content.subList(1,content.size());
            List<User> userList = new ArrayList<>();
            for(int i=0;i<content.size();i++) {
                User u = new User();
                u.setUserid(Integer.parseInt(content.get(i).getContent().getName()));
                userList.add(userService.selectUser(u).get(0));
            }
            map.put("data",content);
            map.put("userInfo",userList);
            map.put("size",content.size());
            map.put("msg","200");
        } catch (Exception e) {
            map.put("msg","500");
            e.printStackTrace();
        }

       return (JSON) JSON.toJSON(map);
    }
    @GetMapping("/selectLevel")
    @ApiOperation(value = "查询用户等级和经验值，row是选前几条(default=10)，默认按等级和经验值降序",notes = "传值进来")
    public JSON selectLevel(EventLevel level,Integer row){
        Map<Object, Object> map = new ConcurrentHashMap<>();
        String msg;
        List<EventLevel> users = levelService.selectLevel(level,row);
        if(users.size()>0) msg="200";
        else msg="500";
        map.put("code",0);
        map.put("msg",msg);
        map.put("count",users.size());
        map.put("data",users);
        JSON json = (JSON) JSON.toJSON(map);
       return json;
    }
    @PostMapping("/updateLevel")
    @ApiOperation(value = "更新等级经验，一定要传用户id",notes = "传值进来")
    public JSON updateLevel(EventLevel level){
        Map<Object, Object> map = new ConcurrentHashMap<>();
        String msg;
        int i = levelService.updateLevel(level);
        if(i>0) msg="200";
        else msg="500";
        map.put("code",0);
        map.put("msg",msg);
        return (JSON) JSON.toJSON(map);
    }
}
